﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using ZeroBugBounce.Missive.Locks;

namespace ZeroBugBounce.Missive
{
	public class Topic
	{
		static Topic()
		{
			Default = Parse(DefaultTopicText);
			All = Parse(AllTopicText);
		}

		public static readonly Topic Default;
		public static readonly Topic All;

		public const string DefaultTopicText = "DefaultTopic-87A67EE1-9403-4887-BDE1-29AB7D5AF2B8";
		public const string AllTopicText = "*";

		public static Topic Parse(object topic)
		{
			string textTopic = topic.ToString().ToLowerInvariant();

			Topic instance = new Topic();

			instance.parts = textTopic.Split('.').Select(part => part.GetHashCode()).ToArray();
			instance.fullTopic = textTopic;
			instance.hash = instance.fullTopic.GetHashCode();

			return instance;
		}

		internal string fullTopic;
		internal int[] parts;
		internal int hash;

		internal Topic()
		{

		}

		public override string ToString()
		{
			return fullTopic;
		}

		public bool IsUnder(Topic topic)
		{
			if (topic.hash == this.hash)
				return true;

			//if (topic.hash == All.hash)
			//    return true;

			if (parts.Length == 1)
				return false;

			if (parts.Length < topic.parts.Length)
				return false;

			for (int partIndex = 0; partIndex < topic.parts.Length; partIndex++)
			{
				//if (string.CompareOrdinal(topic.Parts[partIndex], Parts[partIndex]) != 0)
				//if(string.Compare(topic.Parts[partIndex], Parts[partIndex], StringComparison.InvariantCulture) != 0)

				if (topic.parts[partIndex] != parts[partIndex])
				{
					return false;
				}
			}

			return true;
		}

		public override bool Equals(object obj)
		{
			Topic other = obj as Topic;
			if (other == null)
			{
				return false;
			}
			else
			{
				return hash == other.hash;
			}
		}

		public override int GetHashCode()
		{
			return hash;
		}

		public static bool operator ==(Topic left, Topic right)
		{
			// If both are null, or both are same instance, return true.
			if (System.Object.ReferenceEquals(left, right))
			{
				return true;
			}

			if (((object)left) == null || ((object)right) == null)
			{
				return false;
			}

			return left.hash == right.hash;
		}

		public static bool operator !=(Topic left, Topic right)
		{
			return !(left == right);
		}
	}
}
